use axum::response::sse::{Event, KeepAlive};
use axum::response::Sse;
use futures::{stream, Stream};
use serde::Deserialize;
use std::convert::Infallible;
use std::time::Duration;
use axum::Json;
use tokio_stream::StreamExt as _;
use axum::routing::get;
use crate::redis;

const KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(1);
const CLIENTS_KEY: &str = "online_clients";

#[derive(Debug, Deserialize)]
struct SseParams {
    code: String
}

/// SSE服务的Router接口
///
/// # 返回值
/// - `axum::routing::Router` - 生成的Router
pub fn see_router() -> anyhow::Result<axum::routing::Router> {
    let router = axum::Router::new()
        .route("/sse/connect", get(sse_connect_handler))
        .route("/sse/online", get(sse_online_handler));

    Ok(router)
}

/// SSE router的服务内容
async fn sse_connect_handler(axum::extract::Query(params): axum::extract::Query<SseParams>) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {

    redis::set_set(CLIENTS_KEY, &params.code).await.unwrap();

    let stream = stream::repeat_with(|| {
        let data = format!("Current time: {}", chrono::Local::now().to_rfc3339());
        Event::default().data(data)
    }).map(Ok).throttle(KEEP_ALIVE_INTERVAL);

    Sse::new(stream).keep_alive(KeepAlive::default())
}

/// 获取当前在线人数并转为`axum::json::Json`以满足router的Trat
///
///
///
/// # 返回值
/// - `Json<Vec<String>>` - 当前在线的用户集合
#[axum::debug_handler]
async fn sse_online_handler() -> Json<Vec<String>> {
    let online_clients = redis::get_set_all(CLIENTS_KEY).await.unwrap();
    Json::from(Vec::from_iter(online_clients.clone()))
}